require 'open-uri'
require 'rubygems'
require 'hpricot'
IRCBot::Plugin.define "plugin" do
	$config['global']['plugin_dir'] = $config['global']['plugindir']
	help_string nil
	@no_unload_plugins = %w[plugin auth die restart]
	def command(user,target,message,usermask)
		if IRCBot::Plugin.registered_plugins['auth'].is_auth_user?(usermask) then
			command = message.split[0]
			message = message.sub(command,"").strip
			
			case command
				when "unload"
					status = unload_plugin(message,false)
					case status
						when -2
							privmsg(target,"The plugin \"#{message}\" can't be unloaded.")
						when -1
							privmsg(target,"That plugin isn't loaded.")
						when 0
							privmsg(target,"Plugin \"#{message}\" unloaded.")
						else
							if status.class == Array then
								privmsg(target,"The following plugins depend on #{message}: #{status.join(', ')}. Will not unload.")
							end
					end
				when "load"			
					status = load_plugin(message)
					case status
						when -2
							privmsg(target,"The plugin doesn't exist.")
						when -1
							privmsg(target,"Plugin already loaded.")
						when 0
							privmsg(target,"Plugin loaded.")
						else
							if status.class == Array
								privmsg(target,"That plugin has missing dependencies: #{status.join(', ')}.")
							end
					end
				when "reload"
					status = load_plugin(message,true)
					case status
						when -3
							privmsg(target,"New plugin version isn't sane, falling back.")
						when -2
							privmsg(target,"The plugin doesn't exist.")
						when -1
							privmsg(target,"Plugin already loaded.")
						when 0
							privmsg(target,"Plugin reloaded.")
						else
							if status.class == Array
								privmsg(target,"That plugin has missing dependencies: #{status.join(', ')}")
							end
					end
				when 'update'
					puts "Getting SVN version..."
					t = open('http://marcobot.googlecode.com/svn/trunk/plugins/'+message.downcase+'.rb')
					if t.status == ['200','OK'] then
						puts "Got SVN version."
						puts "Checking local file..."
						fail = false
						begin
							f = open($config['global']['plugin_dir']+'/'+message.downcase+'.rb')
						rescue Exception => e
#							privmsg('#FaiD3.0',e.detail)
							fail = true
							if !File.exists?($config['global']['plugin_dir']+'/'+message.downcase+'.rb') then
								fail = nil
							end
						end
						if fail then
							privmsg(target,'That plugin doesn\'t exist locally.')
						else
							puts "Comparing versions..."
							a = t.readlines.join
							if fail == nil then
								b = ''
							else
								b = f.readlines.join
							end
							if a == b then
								privmsg(target,'Plugin is up-to-date.')
							else
								puts "Plugin is out of date, updating."
								if !File.writable?($config['global']['plugin_dir']) then
									privmsg(target,"Plugin folder not writable.")
								else
									File.rename($config['global']['plugin_dir']+'/'+message.downcase+'.rb',$config['global']['plugin_dir']+'/'+message.downcase+'.rb.ver'+"#{Time.new.hour}-#{Time.new.min}-#{Time.new.sec}--#{Time.new.day}-#{Time.new.mon}-#{Time.new.year}") unless !File.exists?($config['global']['plugin_dir']+'/'+message.downcase+'.rb')
									File.open($config['global']['plugin_dir']+'/'+message.downcase+'.rb','w') do |file|
										file << a
									end
									privmsg(target,'Plugin updated.')
								end
							end
						end
					else
						privmsg(target,'Plugin doesn\'t exist.')
					end
				when 'checkall'
					outdated_plugins = []
					Dir["#{$config['global']['plugindir']}/*.rb"].each do |file|
						name = File.basename(file).split('.')[0]
						
						svn_version = open('http://marcobot.googlecode.com/svn/trunk/plugins/'+name+'.rb').read
						local_version = open(file).read
						if svn_version != local_version then
							outdated_plugins.push name
						end
					end
					privmsg(target,"Outdated plugins: #{outdated_plugins.sort.join(', ')}.")
				when 'update_data'
					data_file = message.split[0]
					faidbin_address = message.sub(data_file,'').strip
					
					remote_data_file = open(faidbin_address).read
					remote_data_file = Hpricot(remote_data_file).search('textarea')[1].inner_html
					File.open($config['global']['plugin_data_dir']+'/'+data_file+'.yml','w') do |file|
						file << remote_data_file
					end
				when 'update_core'
					puts "Getting SVN version..."
					t = open('http://marcobot.googlecode.com/svn/trunk/ircbot.rb')
					if t.status == ['200','OK'] then
						puts "Got SVN version."
						puts "Checking local file..."
						fail = false
						begin
							f = open(Dir.pwd+'/ircbot.rb')
						rescue Exception => e
#							privmsg('#FaiD3.0',e.detail)
							fail = true
							if !File.exists?(Dir.pwd+'/ircbot.rb') then
								fail = nil
							end
						end
						if fail then
							privmsg(target,'That plugin doesn\'t exist locally.')
						else
							puts "Comparing versions..."
							a = t.readlines.join
							if fail == nil then
								b = ''
							else
								b = f.readlines.join
							end
							if a == b then
								privmsg(target,'Core is up-to-date.')
							else
								puts "Plugin is out of date, updating."
								if !File.writable?(Dir.pwd) then
									privmsg(target,"Core not writable.")
								else
									File.rename(Dir.pwd+'/ircbot.rb',Dir.pwd+'/ircbot.rb.ver'+"#{Time.new.hour}-#{Time.new.min}-#{Time.new.sec}--#{Time.new.day}-#{Time.new.mon}-#{Time.new.year}") unless !File.exists?(Dir.pwd+'/ircbot.rb')
									File.open(Dir.pwd+'/ircbot.rb','w') do |file|
										file << a
									end
									privmsg(target,'Core updated. It\' better be sane.')
								end
							end
						end
					else
						privmsg(target,'Plugin doesn\'t exist.')
					end
				else
					privmsg(target,"Unknown option.")
				
			end
		end
	end
	def unload_plugin(name,bypass)
		if !get_plugin(name) then
			return -1
		elsif @no_unload_plugins.include?(name) and !bypass then
			return -2
		else
			if !bypass then
				depending_plugins = []
				for plugin in IRCBot::Plugin.registered_plugins
					if plugin[1].depends then
						if plugin[1].depends.include?(name) then
							depending_plugins << plugin[0]
						end
					end
				end
				if depending_plugins.empty? then
					IRCBot::Plugin.registered_plugins.delete name
					return 0
				else
					return depending_plugins
				end
			else
				IRCBot::Plugin.registered_plugins.delete name
				return 0
			end
		end
	end
	def load_plugin(name,bypass=false)
		if get_plugin(name) and !bypass then
			return -1
		elsif !File.exists?($config['global']['plugindir']+'/'+name+'.rb') then
			return -2
		else
			old_instance = get_plugin(name)
			fail = false
			begin
				load $config['global']['plugindir']+'/'+name+'.rb'
			rescue Exception => e
				privmsg($config[$network]['master_user'],"Got an exception: #{e.message()}")
				privmsg($config[$network]['master_user'],"Backtrace:")
				for detail in e.backtrace()
					privmsg($config[$network]['master_user'],detail)
				end
				privmsg($config[$network]['debug_channel'],"Exception caught while loading plugin '#{name}': #{e.message}")
				fail = true
			end
			
			if fail then
				IRCBot::Plugin.registered_plugins[name] = old_instance
				return -3
			else
				missing_deps = []
				if get_plugin(name).depends then
					for dep in get_plugin(name).depends
						if !get_plugin(dep) then
							missing_deps << dep
						end
					end
				end
				if missing_deps.empty? then
					return 0
				else
					return missing_deps
				end
			end
		end
	end
end
